package com.gitee.wsl.statemachine.task

import com.gitee.wsl.flow.state.IStateSource
import com.gitee.wsl.flow.state.IStateSourceWithSharedFlow
import com.gitee.wsl.flow.state.StateSourceSharedFlowDecorator
import kotlinx.atomicfu.locks.SynchronizedObject
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow

abstract class Feature<STATE , ACTION>(
    val synchronizedObject: SynchronizedObject = SynchronizedObject(),
    state: IStateSource<STATE>,
) {
    val stateSource: IStateSourceWithSharedFlow<STATE> = StateSourceSharedFlowDecorator(state)
    /**
     * Provides a [flow][StateFlow] of [states][State]
     *
     * @return a [flow][StateFlow] of [states][State]
     */
    fun observeState(): StateFlow<STATE> = stateSource.observeState()

    /**
     * Provides a [flow][SharedFlow] of [states][State] for AsyncWorker
     *
     * @return a [flow][SharedFlow] of [states][State]
     */
    internal  fun observeAllStates(): SharedFlow<STATE> = stateSource.observeAllStates()

    /**
     * Returns current state
     *
     * @return current [state][State]
     */
    fun getCurrentState(): STATE = stateSource.getCurrentState()

    /**
     * Submits an [action][Action] to be executed to the [store][Store]
     *
     * @param action [Action] to run
     */
    abstract fun proceed(action: ACTION)

    companion object
}